﻿using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace DataServer.View
{
    /// <summary>
    /// WaitingBox.xaml 的交互逻辑
    /// </summary>
    public partial class WaitingBox
    {
        public string Text { get { return this.txtMessage.Text; } set { this.txtMessage.Text = value; } }

        private Action _Callback;
        protected bool CanBeCanceled = false;
        protected bool RunBackground = true;
        private DispatcherTimer _timer;
        private Task _task;
        private CancellationTokenSource _tokenSource;

        public WaitingBox(Action callback)
        {
            InitializeComponent();
            this._Callback = callback;
            this.Loaded += WaitingBox_Loaded;
        }

        void WaitingBox_Loaded(object sender, RoutedEventArgs e)
        {
            if (RunBackground)
            {
                CancellationToken token;
                if (!CanBeCanceled)
                {
                    token = new CancellationToken(false);
                }
                else
                {
                    _tokenSource = new CancellationTokenSource();
                    token = _tokenSource.Token;
                }
                _timer = new DispatcherTimer(DispatcherPriority.Background);
                _timer.Interval = TimeSpan.FromMilliseconds(100);
                _timer.Tick += _timer_Tick;
                _timer.Start();
                 _task = Task.Factory.StartNew(this._Callback, token);
                if (CanBeCanceled)
                {
                    btnCancel.Visibility = Visibility.Visible;
                }
            }
            else
            {
                this._Callback.BeginInvoke(this.OnComplate, null);
            }
        }
        private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
        {
            try
            {
                _tokenSource?.Cancel();
            }
            catch
            {
            }
           
        }
        private void _timer_Tick(object sender, EventArgs e)
        {
            //DoEvents();
            if (_task.IsCompleted)
            {
                this.Close();
            }
        }

        private void OnComplate(IAsyncResult ar)
        {
            this.Dispatcher.Invoke(() =>
            {
                this.Close();
            });
        }
        /// <summary>
        /// 显示等待框，owner指定宿主视图元素，callback为需要执行的方法体（需要自己做异常处理）。
        /// 目前等等框为模式窗体
        /// </summary>
        public static void Show(FrameworkElement owner, Action callback, string mes = "任务执行中...",bool backgroud= true, bool bCanceled = false)
        {
            WaitingBox win = new WaitingBox(callback);
            win.RunBackground = backgroud;
            win.CanBeCanceled = bCanceled;
            Window pwin = GetWindow(owner);
            win.Owner = pwin;
            win.Text = mes;
            var loc = owner.PointToScreen(new Point());
            win.Left = loc.X + (owner.ActualWidth - win.Width) / 2;
            win.Top = loc.Y + (owner.ActualHeight - win.Height) / 2;
            win.ShowDialog();
        }
        private static void DoEvents()
        {
            DispatcherFrame frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame);
            Dispatcher.PushFrame(frame);
        }

        private static Object ExitFrame(Object state)
        {
            ((DispatcherFrame)state).Continue = false;
            return null;
        }

    }
}
